print("------------ 函数参数泛型 ------------")
func getValue<T>(_ arg: T) -> T {
    print("函数内部的打印\(arg)")
    return(arg)
}
print(getValue(1))

// 泛型的名字"T"可以自定义: <Setence>
class Generiticity<Setence> {
    var name: String = "Felix"
    func say(_ word: Setence) {
        print(word)
    }
}

// 使用的时候可以指定类型, 也可以不指定
var g = Generiticity<Any>()
g.say(123)
g.say("good1")
g.say("false")

print("------------ 关联类型(协议里面使用泛型) ------------")
protocol Container {
    // 遵守Equatable协议的ItemType
    associatedtype ItemType: Equatable
    
    mutating func append(_ item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct IntStack: Container {
    var items = [Int]()
    
    typealias ItemType = Int
    
    // 遵守协议
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> Int {
        return items[i]
    }
}

var intStack = IntStack()
intStack.append(1)
intStack.append(2)
print(intStack.count)
print(intStack[0])
